package aole;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main2 extends Application {
	private StringProperty						team1;
	private StringProperty						team2;

	private StringProperty						battingTeam;

	private PlayerMatchInfo						striker;
	private PlayerMatchInfo						nonStriker;

	private ObservableList< PlayerMatchInfo >	data;
	private ObservableList< PlayerMatchInfo >	data1;
	private ObservableList< PlayerMatchInfo >	data2;
	private TableView< PlayerMatchInfo >		table;

	private boolean								matchComplete;
	private int									totalBalls;

	private Label								lblScore	= new Label();

	private Timeline							timeline;
	private int									totalRuns;
	private int									totalWickets;

	enum ball_type {
		Pathetic, Bad, Average, Good, Excellent,
	}

	enum hit_type {
		Middle, HalfOut, HalfIn, EdgeOut, EdgeIn, MissOut, MissIn,
	}

	@Override
	public void start( Stage stage ) throws Exception {
		// create UI
		BorderPane root = new BorderPane();
		Scene scene = new Scene( root, 800, 600 );

		showStartScreen( root );

		stage.setScene( scene );
		stage.show();
	}

	private void showStartScreen( final BorderPane root ) {
		Label l = new Label( "Enter team names" );

		Label t1 = new Label( "Team 1:" );
		TextField txt1 = new TextField( "Team1" );
		team1 = new SimpleStringProperty();
		team1.bind( txt1.textProperty() );
		HBox hbox1 = new HBox( 5 );
		hbox1.getChildren().addAll( t1, txt1 );

		Label t2 = new Label( "Team 2:" );
		TextField txt2 = new TextField( "Team2" );
		team2 = new SimpleStringProperty();
		team2.bind( txt2.textProperty() );
		HBox hbox2 = new HBox( 5 );
		hbox2.getChildren().addAll( t2, txt2 );

		Button b = new Button( "Start Match" );
		b.setOnAction( new EventHandler< ActionEvent >() {

			@Override
			public void handle( ActionEvent ae ) {
				showMatchControls( root );
			}
		} );

		VBox vbox = new VBox( 5 );
		vbox.getChildren().addAll( l, hbox1, hbox2, b );

		Group g = new Group( vbox );
		root.setCenter( g );
	}

	protected void showMatchControls( BorderPane root ) {
		HBox hbox = new HBox();
		hbox.getChildren().addAll( lblScore );

		root.setBottom( hbox );

		// right pane
		Button i1 = new Button( "1st Inings" );
		i1.setOnAction( new EventHandler< ActionEvent >() {

			@Override
			public void handle( ActionEvent arg0 ) {
				battingTeam.set( team1.get() );
				table.setItems( data1 );
			}

		} );

		Button b = new Button( "Play" );
		b.setOnAction( new EventHandler< ActionEvent >() {

			@Override
			public void handle( ActionEvent ae ) {
				matchComplete = false;
				timeline = new Timeline( new KeyFrame( Duration.ZERO,
						new EventHandler< ActionEvent >() {
							@Override
							public void handle( ActionEvent event ) {
								bowlNextBall();
							}
						} ), new KeyFrame( Duration.millis( 10 ) ) );
				timeline.setCycleCount( Timeline.INDEFINITE );
				timeline.play();
			}
		} );
		Button i2 = new Button( "2nd Inings" );
		i2.setOnAction( new EventHandler< ActionEvent >() {

			@Override
			public void handle( ActionEvent arg0 ) {
				battingTeam.set( team2.get() );
				table.setItems( data2 );
			}

		} );

		VBox vbox = new VBox();
		vbox.getChildren().addAll( b, i1, i2 );

		root.setRight( vbox );
	}

	private int	sixes;
	private int	fours;
	private int	threes;
	private int	twos;
	private int	ones;
	private int	dots;

	protected void bowlNextBall() {
		totalBalls++;
		// ball_type bt = getBallType();
		// System.out.print( bt + ":" );
		hit_type ht = getHitType();
		// System.out.print( ht + ":" );

		// int r = getRuns( bt, ht );
		int r = getRuns2( ht );

		// System.out.println( r );

		if( r == 6 ) sixes++;
		if( r == 4 ) fours++;
		if( r == 3 ) threes++;
		if( r == 2 ) twos++;
		if( r == 1 ) ones++;
		if( r == 0 ) dots++;

		if( r < 0 )
			totalWickets++;
		else totalRuns += r;

		if( totalBalls % 120 == 0 ) matchComplete = true;

		lblScore.setText( totalRuns + " for " + totalWickets + " in "
				+ totalBalls );
		if( matchComplete ) {
			timeline.stop();
			System.out.println( "----Hit----" );
			System.out.println( hitMiddle );
			System.out.println( hitHalfOut );
			// System.out.println( hitHalfIn );
			System.out.println( hitEdgeOut );
			// System.out.println( hitEdgeIn );
			System.out.println( hitMissOut );
			// System.out.println( hitMissIn );
			// System.out.println( "----Runs----" );
			System.out.println( sixes );
			System.out.println( fours );
			System.out.println( threes );
			System.out.println( twos );
			System.out.println( ones );
			System.out.println( dots );
			System.out.println( totalWickets );
			System.out.println( totalRuns );
		}
	}

	private int getRuns2( hit_type ht ) {
		double r;
		boolean arial = false;
		boolean infield = false;
		boolean outfield = false;
		boolean slips_keeper = false;

		if( ht == hit_type.MissIn || ht == hit_type.MissOut ) {
			// the ball is completely missed
			// did it hit the stumps?
			r = Math.random();
			if( r < .25 ) return -1;
			return 0;
		}

		// was the shot arial?
		r = Math.random();
		if( r < .15 ) arial = true;
		// is there a fielder in infield
		r = Math.random();
		if( r < .35 ) infield = true;
		// is there a fielder in outfield
		r = Math.random();
		if( r < .50 ) outfield = true;

		if( ht == hit_type.Middle ) {
			if( arial ) return 6;
			// ground shot
			if( infield ) return 0;
			if( outfield ) return 1;
			return 4;
		}

		if( ht == hit_type.HalfIn || ht == hit_type.HalfOut ) {
			if( arial ) {
				if( outfield ) return -1;
				return 4;
			}
			// ground shot
			if( infield ) return 0;
			if( outfield ) return 1;
			return 2;
		}

		// did the ball goto slips or keeper?
		r = Math.random();
		if( r < .4 ) slips_keeper = true;

		if( ht == hit_type.EdgeIn || ht == hit_type.EdgeOut ) {
			if( arial ) {
				if( slips_keeper ) return -1;
				return 4;
			}
			if( slips_keeper ) return 0;

			// 75% chance of 1
			r = Math.random();
			if( r < .75 ) return 1;
			return 2;
		}
		return 0;
	}

	private int	hitMiddle;
	private int	hitHalfOut;
	private int	hitHalfIn;
	private int	hitEdgeOut;
	private int	hitEdgeIn;
	private int	hitMissOut;
	private int	hitMissIn;

	private hit_type getHitType() {
		double r = Math.random();

		if( r < 0.05 ) {
			hitMissOut++;
			return hit_type.MissOut;
		}
		/*
		 * if( r < 2 / 8. ) { hitMissIn++; return hit_type.MissIn; }
		 */
		if( r < 0.20 ) {
			hitEdgeOut++;
			return hit_type.EdgeOut;
		}
		/*
		 * if( r < 4 / 8. ) { hitEdgeIn++; return hit_type.EdgeIn; }
		 */
		if( r < .65 ) {
			hitHalfOut++;
			return hit_type.HalfOut;
		}
		/*
		 * if( r < 6 / 8. ) { hitHalfIn++; return hit_type.HalfIn; }
		 */
		hitMiddle++;
		return hit_type.Middle;
	}

	public static void main( String[] args ) {
		launch( args );
	}

}